﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Configuration;

namespace Sinacor.Infra.Tools.ServiceGenerator.Loader
{
    class Program
    {
        private static DateTime _dateChange;

        static void Main(string[] args)
        {
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine(string.Format("Inicio do ServiceLoader. Data e Hora {0}", DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss")));
            Console.WriteLine(" ");

            const string pattern = "*.dll";
            
            try
            {
                string dropPath = Path.GetFullPath(args.Length == 0 ? ConfigurationManager.AppSettings["DropPath"] ?? Environment.CurrentDirectory : args[0]);

                Console.Title = dropPath + Path.DirectorySeparatorChar + pattern;

                _dateChange = DateTime.Now;
                //_dateChange = new DateTime(2009, 07, 02, 09, 26, 10);

                if (!Directory.Exists(dropPath))
                    throw new DirectoryNotFoundException(dropPath);

                
                if (Directory.GetDirectories(dropPath).Length > 0)
                    LoadDirectories(dropPath, pattern);
                else
                    LoadFiles(dropPath, pattern);

            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex.Message);
            }

            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine(" ");            
            Console.WriteLine(string.Format("Termino do ServiceLoader. Data e Hora {0}", DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss")));
        }

        private static void LoadDirectories(string directoryRoot, string pattern)
        {
            foreach (string directoryName in Directory.GetDirectories(directoryRoot))
            {
                LoadFiles(directoryName, pattern);
                LoadDirectories(directoryName, pattern);
            }
        }

        private static void LoadFiles(string directoryName, string pattern)
        {
            foreach (string assemblyFile in Directory.GetFiles(directoryName, pattern))
            {
                Create(Path.GetFullPath(assemblyFile));
            }
        }

        static void Create(string assemblyFile)
        {
            try
            {
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine("Reading {0}", Path.GetFileName(assemblyFile));
                
                AssemblyLoader loader = new AssemblyLoader();
                loader.LoadServices(assemblyFile, _dateChange);
            }
            catch (System.Reflection.ReflectionTypeLoadException ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Cannot read assembly file: {0}", Path.GetFileName(assemblyFile));
                Console.WriteLine(ex.Message);
                int rtle_count = ((System.Reflection.ReflectionTypeLoadException)ex).LoaderExceptions.Count();
                int rtle_index = 1;
                if (rtle_count != 0)
                {
                    Exception[] rtle_array = ((System.Reflection.ReflectionTypeLoadException)ex).LoaderExceptions;
                    foreach (Exception rtle in rtle_array)
                    {
                        Console.WriteLine("LoadException({0}/{1}): {2}", rtle_index, rtle_count, rtle.Message);
                        rtle_index++;
                    }
                }
                Console.WriteLine("");
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("Cannot read assembly file: {0}", Path.GetFileName(assemblyFile));
                Console.WriteLine(ex.Message);
                Console.WriteLine("");
            }
        }
    }
}
